package com.aspectj.aop;

import java.lang.reflect.Modifier;

import org.springframework.stereotype.Component;

import com.aspectj.anno.After;
import com.aspectj.anno.AfterReturning;
import com.aspectj.anno.AfterThrowing;
import com.aspectj.anno.Aspect;
import com.aspectj.anno.Before;
import com.aspectj.anno.Pointcut;
import com.aspectj.param.JoinPoint;
import com.aspectj.param.ProceedingJoinPoint;

/**
 * @desc: 经纪人切面
 * @author: CSH
 **/
@Aspect
//@Component
public class BrokerAspect2 {

	/**
	 * 定义切入点，切入点为com.aspectj.service.AopService中的所有函数 通过@Pointcut注解声明频繁使用的切点表达式
	 */
	@Pointcut("com.aspectj.service")
	public void brokerAspect() {

	}

	/**
	 * @description 在连接点执行之前执行的通知
	 */
	@Before("brokerAspect()")
	public void doBeforeGame(JoinPoint joinPoint) {
		//print(joinPoint);
		System.out.println("doBeforeGame2");
	}

	private void print(JoinPoint joinPoint) {
		System.out.println("目标方法名为:" + joinPoint.getSignature().getName());
		System.out.println("目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
		System.out.println("目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
		System.out.println("目标方法声明类型:" + Modifier.toString(joinPoint.getSignature().getModifiers()));
		// 获取传入目标方法的参数
		Object[] args = joinPoint.getArgs();
		if (args != null && args.length > 0) {
			for (int i = 0; i < args.length; i++) {
				System.out.println("第" + (i + 1) + "个参数为:" + args[i]);
			}
		}
		System.out.println("被代理的对象:" + joinPoint.getTarget());
		System.out.println("代理对象自己:" + joinPoint.getThis());
	}

	/**
	 * @description 在连接点执行之后执行的通知（返回通知和异常通知的异常）
	 */
	@After("brokerAspect()")
	public void doAfterGame(JoinPoint joinPoint) {
		System.out.println("doAfterGame");
	}

	/**
	 * @description 在连接点执行之后执行的通知（返回通知）
	 */
	@AfterReturning("brokerAspect()")
	public void doAfterReturningGame(JoinPoint joinPoint) {
		System.out.println("返回通知：BrokerAspect");
	}

	/**
	 * @description 在连接点执行之后执行的通知（异常通知）
	 */
	@AfterThrowing("brokerAspect()")
	public void doAfterThrowingGame(JoinPoint joinPoint, Exception e) {
		System.out.println("异常通知：doAfterThrowingGame");
		System.out.println("发生异常：e="+e.getCause().getMessage());
	}

	/**
	 * @description 环绕
	 */
	//@Around("brokerAspect()")
	public Object doArroundGame(ProceedingJoinPoint pjp) {
		System.out.println("环绕通知开始：doArroundGame");
		Object res = null;
		try {
			//print(pjp);
			res = pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		System.out.println("环绕通知结束：doArroundGame");
		return res;
	}
}